/******************************************************************************
**
** File name:	rtos.h
**
** Description:	RTOS (Real Time Operating System) Version 0.0.1
**				Main user header file. Do not modify this file!
**
** Author:		Alexey.Khomich@gmail.com
**
*******************************************************************************
** History:		
**  
**	10/05/2011	- AK -	RTOS V.2 TASK/ISR services reimplemented
**						kernel/task/isr typedefs are changed
**  10/15/2011	- AK - 	Adding basic event management
**	11/14/2011	- AK - 	Cosmetic changes (var names, defs)
** 	11/15/2011 	- AK - 	Adding messages, message queues and timers
**	11/19/2011 	- AK -	Removing obsolete services, about to final revision for 
**						RTOS V.2
**	11/25/2011  - AK -  Adding resource export macros
**  11/30/2011	- AK -  cast task' stack to RTOS_CTX_t
**  03/16/2012	- AK -  Starting from scratch
**  03/16/2012	- AK -  Adding simple static config
** 
******************************************************************************/
#ifndef __RTOS_H__
#define __RTOS_H__

/******************************************************************************
** RTOS CONFIGURATION SECTION
******************************************************************************/
#define RTOS_VERSION_MAJOR				0		/* RTOS Version 0.0 */
#define RTOS_VERSION_MINOR				0

#define RTOS_USE_STACKCHECK				1		/* Enable/Disable run-time stack verification capabilities */
#define RTOS_USE_TASKS					1
#define	RTOS_USE_EVENTS					1
#undef	RTOS_USE_MESSAGES
#undef	RTOS_USE_QUEUES
#undef	RTOS_USE_TIMERS

/******************************************************************************
**
** Compiler related defines 
**
******************************************************************************/
#if !defined( __GNUC__ )  /* Supporting GNU toolchain from AVR Studio 5.0 and 5.1 */
#error "Error: No compiler is supported other than GNU Toolchain"
#endif

#define FLASH			__attribute__ ((progmem))
#define EEPROM			__attribute__ ((section(".eeprom")))
#define NAKED			__attribute__ ((naked))
#define CTASK			__attribute__ ((noreturn))
#define NAKEDFUNC(A) 	void A(void) NAKED;\
						void A(void)
#define CTASKFUNC(A) 	void A(void) CTASK;\
						void A(void)
#define RTOS_API		extern


/******************************************************************************
** RTOS Type Definitions
******************************************************************************/
/* RTOS ELEMENTARY TYPES */
typedef unsigned char 	RTOS_U8_t;
typedef unsigned int  	RTOS_U16_t;
typedef unsigned long 	RTOS_U32_t;

/* RTOS KERNEL PRIVATE STRUCTURE */
typedef struct RTOS_KDATA_s
{
	struct RTOS_PID_s *	queue;				// Head of the running tasks queue 
	struct RTOS_PID_s *	running;			// Actually running task
	void *				stack;				// Kernel stack pointer
	RTOS_U8_t			level;				// System execution level 
	
}
RTOS_KDATA_t;

/* RTOS TASK CONTEXT */
/* RTOS CONTEXT TYPE */
typedef struct RTOS_CTX_s
{
	RTOS_U8_t				STACKTOP;		// Top of the task stack
	RTOS_U8_t				STATUSREG;		// MCU STATUS REGISTER
	RTOS_U8_t				R[32];			// REGISTERS R0 ... R31
	RTOS_U16_t				RETADDR;		// RETURN ADDRESS (reverse bytes order)
//	U8			RET_HI;
//	U8			RET_LO;
}
RTOS_CTX_t, * RTOS_CTX_ptr;


/* RTOS TASK/ISR FUNCTIONS */
typedef void ( RTOS_TSK_t ) (void);
typedef void ( RTOS_ISR_t )	(void);

/* RTOS TCB - TASK CONFIGURATION BLOCK */
typedef struct RTOS_TCB_s					// RTOS Task Configuration Block (TCB)
{
    RTOS_CTX_t *			stack;          // Start of stack (top address-1)
    RTOS_TSK_t *			task;   		// Entry point of code
    struct RTOS_PID_s *		pid;         	// Pointer to Task ID block
    RTOS_U8_t 				prio;       	// Priority of task (0-255)	
}
FLASH const RTOS_TCB_t;

/* RTOS PID - PROCESS (TASK) IDENTIFIER */
typedef struct RTOS_PID_s					
{
	struct RTOS_PID_s *		next;
	RTOS_U8_t	 			flag;
	RTOS_U8_t 				prio;
	RTOS_CTX_t *			sptr;
}
RTOS_PID_t, * RTOS_PID_ptr;

/* RTOS EVT - EVENT */
typedef struct RTOS_EVT_s
{
	struct RTOS_EVT_s *	next;
}
RTOS_EVT_t, * RTOS_EVT_ptr;

/* RTOS EST - EVENT STATE */
typedef enum RTOS_EST_e
{
	EVT_PEND	= 0,						// Event Pending 
	EVT_DONE	= 1,						// Event Done
	EVT_WAIT	= 2,						// Something is waiting for the event	
}
RTOS_EST_t, * RTOS_EST_ptr;

/* RTOS EST - EVENT STATE */

/* TBD */

/* RTOS MSG - MESSAGE */

/* TBD */

/* RTOS MSQ - MESSAGE QUEUE */

/* TBD */

/* RTOS TMR - TIMER */

/* TBD */

/* RTOS OBJ - OBJECT */
typedef union RTOS_OBJ_u
{
	struct RTOS_PID_s		pid;
//	struct RTOS_MSG_s		msg;
//	struct RTOS_MSQ_s		msq;
//	struct RTOS_TMR_s		tmr;
}
RTOS_OBJ_t, * RTOS_OBJ_ptr;

/******************************************************************************
** RTOS CONSTANT DEFINITIONS
******************************************************************************/
#if !defined(NULL)
#	define	NULL	0
#endif

#define NOTASK		((RTOS_TCB_t *)NULL)
#define NOMESSAGE	((RTOS_MSG_t *)NULL)
#define NOTIMER		((RTOS_TMR_t *)NULL)

/******************************************************************************
** TASK DECLARATION/DEFINITION MACRO
******************************************************************************/
#if defined(RTOS_USE_STACKCHECK)

#define RTOS_DECLARE_TASK( __task__ , __stack__ , __prio__ ) 		\
	struct 															\
	{																\
		RTOS_U32_t		bottom;										\
		RTOS_U8_t		stack[__stack__ + sizeof(RTOS_CTX_t)];		\
		RTOS_U32_t		top;										\
	}																\
	__task__##STK;													\
	void		__task__##FNC ( void ) __attribute__ ((noreturn));	\
	RTOS_PID_t	__task__##PID;										\
	RTOS_TCB_t	__task__##TCB = 									\
	{																				\
		((RTOS_CTX_t *)(&__task__##STK.stack[sizeof(__task__##STK.stack) - 1])),	\
		&__task__##FNC,																\
		&__task__##PID,												\
		__prio__,													\
	}

#else

#define RTOS_DECLARE_TASK( __task__ , __stack__ , __prio__ ) 		\
	RTOS_U8_t	__task__##STK[__stack__ + sizeof(RTOS_CTX_t)];		\
	RTOS_TSK_t	__task__##FNC __attribute__ ((noreturn));			\
	RTOS_PID_t	__task__##PID;										\
	RTOS_TCB_t	__task__##TCB = 									\
	{																	\
		((RTOS_CTX_t *)(&__task__##STK[sizeof(__task__##STK) - 1],))	\
		&__task__##FNC,													\
		&__task__##PID,												\
		__prio__,													\
	}

#endif /* if defined(RTOS_USE_STACKCHECK) */
	
#define RTOS_TASK_FUNC( __task__ )									\
	CTASKFUNC(__task__##FNC)
		
/******************************************************************************
** RTOS INTERRUPT SERVICE ROUTINE DECLARATION/DEFINITION MACRO 
******************************************************************************/

#define RTOS_DECLARE_ISR( __vector__ , __handler__ )				\
	void __handler__##FNC( void );									\
	NAKEDFUNC( __vector__ )											\
	{																\
		rtos_enter_isr();											\
		__handler__##FNC();											\
		rtos_leave_isr();											\
	}
	
#define RTOS_ISR_FUNC( __handler__ )								\
	void __handler__##FNC ( void ) 

/******************************************************************************
** RTOS RESOURCES (EVENT/MESSAGE/QUEUE/TIMER) DECLARATION/DEFINITION MACRO 
******************************************************************************/
#if defined( RTOS_USE_EVENTS )
#define RTOS_DECLARE_EVENT( __evt__ )								\
	RTOS_EVT_t		__evt__
#endif /* RTOS_USE_EVENTS */	

#if defined( RTOS_USE_MESSAGES )
#define RTOS_DECLARE_MESSAGE( __msg__ )								\
    RTOS_MSG_t 		__msg__
#endif /* RTOS_USE_MESSAGES  */

#if defined( RTOS_USE_QUEUES )
#define RTOS_DECLARE_MESSAGEQ( __msq__ )							\
    RTOS_MSQ_t		__msq__
#endif /* RTOS_USE_QUEUES */
	
#if defined( RTOS_USE_TIMERS ) 	
#define RTOS_DECLARE_TIMER( __tmr__ )								\
	RTOS_TMR_t		__tmr__
#endif /* RTOS_USE_TIMERS */
	
/******************************************************************************
** RTOS RESOURCE (TASK/ISR/EVENT/MESSAGE/QUEUE/TIMER) EXPORT MACROS
******************************************************************************/	
#define EXPORT_RTOS_TASK( __tsk__ )									\
	extern void __tsk__##FNC( void) __attribute__((noreturn));		\
	extern RTOS_TCB_t 	__tsk__##TCB;	 							\
	extern RTOS_PID_t 	__tsk__##PID

#define EXPORT_RTOS_ISR( __isr__ )									\
	extern void __isr__##FNC( void )
	
#define EXPORT_RTOS_EVENT( __evt__ )								\
	extern RTOS_EVT_t	__evt__

#define EXPORT_RTOS_MESSAGE( __msg__ ) 								\
	extern RTOS_MSG_t	__msg__
	
#define EXPORT_RTOS_MESSAGEQ( __msq__ ) 							\
	extern RTOS_MSQ_t	__msq__

#define EXPORT_RTOS_TIMER( __tmr__ ) 								\
	extern RTOS_TMR_t	__tmr__
	
/******************************************************************************
** RTOS API SERVICES
******************************************************************************/

/* RTOS KERNEL MANAGEMENT API */

#			define		rtos_disable_interrupt() asm volatile ("cli\n")
#			define		rtos_enable_interrupt()  asm volatile ("sei\n")

RTOS_API 	void * 		rtos_initialize_os		( void * sptr );
RTOS_API 	void 		rtos_start_os			( void );
RTOS_API 	void 		rtos_enter_isr	   		( void );
RTOS_API 	void 		rtos_leave_isr			( void );
RTOS_API 	void 		rtos_halt_os			( void );		// Halt Processor (debug only)

/* RTOS TASK MANAGEMENT API */

#if defined(RTOS_USE_STACKCHECK)

#	define 				rtos_task_start_exp( __task__ )				\
		__task__##STK.top    = 0xDEADBEAFUL;						\
		__task__##STK.bottom = 0xDEADBEAFUL;						\
		rtos_task_start(&(__task__##TCB))
		
#	define 				rtos_task_init_exp( __task__ )				\
		__task__##STK.top    = 0xDEADBEAFUL;						\
		__task__##STK.bottom = 0xDEADBEAFUL;						\
		rtos_task_init(&(__task__##TCB))
		
#	define				rtos_stack_check( __task__ )				\
		(__task__##STK.top    != 0xDEADBEAFUL ) ? rtos_halt_os() :	\
		(__task__##STK.bottom != 0xDEADBEAFUL ) ? rtos_halt_os() : 0
		
#endif	/* if defined(RTOS_USE_STACKCHECK) */

RTOS_API 	void 		rtos_task_start			( RTOS_TCB_t * );
RTOS_API unsigned char 	rtos_task_init			( RTOS_TCB_t * );
RTOS_API 	void 		rtos_task_resume		( RTOS_PID_t * );
RTOS_API 	void 		rtos_task_resume_isr	( RTOS_PID_t * );		
RTOS_API 	void 		rtos_task_suspend		( RTOS_PID_t * );
RTOS_API 	void 		rtos_task_terminate		( RTOS_PID_t * );
RTOS_API 	void 		rtos_task_exit			( void );
RTOS_API 	void 		rtos_task_yield			( void );
RTOS_API 	void 		rtos_task_yield_isr		( void );
#			define 		RTOS_GetTCB(__task__) 	&(__task__##TCB)
#			define 		RTOS_GetPID(__task__) 	&(__task__##PID)

/* RTOS TASK/EVENT MANAGEMENT API */

RTOS_API 	void 		rtos_task_wait			( RTOS_PID_t * );
RTOS_API RTOS_EST_t 	rtos_task_event_test	( RTOS_PID_t * );		// is it really needed?

/* RTOS EVENT MANAGEMENT API  */

RTOS_API 	void 		rtos_event_set			( RTOS_EVT_t * );
RTOS_API 	void 		rtos_event_set_isr		( RTOS_EVT_t * );		

RTOS_API 	void 		rtos_event_reset		( RTOS_EVT_t * );
RTOS_API 	void 		rtos_event_reset_isr	( RTOS_EVT_t * );

RTOS_API RTOS_EST_t		rtos_event_test			( RTOS_EVT_t * );
RTOS_API RTOS_EST_t 	rtos_event_test_isr		( RTOS_EVT_t * );

RTOS_API 	void 		rtos_event_wait			( RTOS_EVT_t * );

RTOS_API 	void 		rtos_object_event_reset	( RTOS_OBJ_t * );		// obsolete, to be used only inside Kernel 

/* RTOS MESSAGE MANAGEMENT API */

/* TBD */

/* RTOS TIMER MANAGEMENT API */

/* TBD */

/* RTOS TIMER MESSAGE MANAGEMENT API */

/* TBD */

/******************************************************************************
** EOF                                                                  
******************************************************************************/
#endif /* __RTOS_H__ */
